# IMPORT


# NAMESPACE - CONTRIB
namespace eval contrib {
    # EXPORT ALL PROCS
    namespace export *
    
    proc localTime {} {
        # RETURN A FORMATED LOCAL TIME
        return [clock format [clock seconds] -format "%Y-%m-%d %H:%M:%S"]
    }
    
    proc withOpen {fhName fh cmds} {
        # CLOSE FILE HANDLER AUTOMATICALLY AFTER OPEN THE FILE
        uplevel [subst {
            set $fhName $fh
            eval {$cmds}
            close $fh
            unset $fhName
        }]
    }
    
    proc spit {fileName msg} {
        # WRITE MESSAGE TO A FILE
        withOpen f [open $fileName a] {
            puts $f $msg
        }
    }

    proc projectRoot {} {
        # RETURN THE ROOT OF PROJECT
        set cwd [pwd]
        if [file isfile [file join $cwd project.tcl]] {
            withOpen fh [open project.tcl r] {
                while {[set length [gets $fh line]] >= 0} {
                    if {$length == 0} {continue}
                    if [regexp {^\s*\#PROJECT\s*:\s*(\S+)} $line match project] { break }
                }
            }
        }
        # if [info exists project] {puts "$cwd, $project"}
        if {[info exists project] && [file tail $cwd] == $project} {
            return $cwd
        } else {
            cd ..; set newCwd [pwd]
            set root {}
            if {$cwd != $newCwd} {
                set root [projectRoot]
            }
            cd $cwd
            return $root
        }
    }
    
    proc importProjectContext {} {
        uplevel #0 {
            source [file join $projectRoot project.tcl]
            namespace eval ::tank {
                variable main [file join $projectRoot src $::main] dependencies $::dependencies description $::description version $::version
            }
            foreach pkg $::tank::dependencies {
                package require $pkg
            }
        }
    }
    
    proc sourceDir {dir} {
        # DEEP FIRST
        set dirs {}
        foreach f [glob -nocomplain -directory $dir *] {
            if {[file isdirectory $f]} {
                lappend dirs $f
            } elseif {[file isfile $f]} {
                uplevel #0 source [file join $dir $f]
            }
        }
        foreach d $dirs {
            sourceDir $d
        }
    }
    
    proc tranverseDir {dir handle} {
        set dirs {}
        foreach f [glob -nocomplain -directory $dir *] {
            if {[file isdirectory $f]} {
                lappend dirs $f
            } elseif {[file isfile $f]} {
                eval $handle $f
            }
        }
        foreach d $dirs {
            tranverseDir $d $handle
        }
    }
    
    # NESTED NAMESPACE - LOG
    namespace eval log {
        proc info {msg} {
            # OUTPUT INFO LOG TO STDOUT
            # puts [format "\[\%s] $msg" [::contrib::localTime]]
            puts "\[[::contrib::localTime]] $msg"
        }
        
        proc error {file msg} {
            # OUTPYTS ERROR LOG TO A FILE
            # ::contrib::spit $file [format "\[\%s] $msg" [::contrib::localTime]]
            ::contrib::spit $file "\[[::contrib::localTime]] $msg"
        }
    }
}

# TEST
if {$argv0 == [info script]} {
    namespace import ::contrib::*
    cd d:/codes/tcl/TankTest/test
    puts [projectRoot]
}